package com.java.java8.lambda.Stream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.DoubleSummaryStatistics;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * https://www.cnblogs.com/yueshutong/p/9735157.html
 * https://objcoding.com/2019/03/04/lambda/#lambda-and-collections
 * https://www.runoob.com/java/java8-new-features.html
 * һ��lambda
	1.����
	2.lambda���ʽ
	��������
	��������
	3.lambda�ܽ�
       ����Stream
	1.������Stream
	2.Stream�ص�
	3.����Stream�ķ�ʽ
	4.Stream���м����
	5.Stream����ֹ����
 */
public class A1 {

	/**
	1.������Stream#
		Stream ���Ǽ���Ԫ�أ����������ݽṹ�����������ݣ������й��㷨�ͼ���ģ�������һ���߼��汾�� Iterator������˵���������þ���ͨ��һϵ�в���������Դ�����ϡ����飩ת��Ϊ��Ҫ�Ľ����
	2.Stream�ص�#
		Stream �ǲ���洢Ԫ�صġ�
		Stream ����ı�ԭ�����෴�����ǻ᷵��һ�����н������Stream��
		Stream �������ӳ�ִ�еġ���ζ�����ǻ�ȵ���Ҫ�����ʱ���ִ�С�
	 */
	public static void main(String[] args) {
		end();
	}

	/**3.����Stream�ķ�ʽ*/
	public static void create() {
		//Collectionϵ�� stream() �� parallelStream();
		List<String> list = new ArrayList<>();
		Stream<String> stream = list.stream();
		Stream<String> stringStream = list.parallelStream();

		//ͨ��Arrays
		Stream<String> stream1 = Arrays.stream(new String[10]);

		//ͨ��Stream
		Stream<Integer> stream2 = Stream.of(1, 2, 3);

		//������
		//����
		Stream<Integer> iterate = Stream.iterate(0, (x) -> x + 2);
		iterate.limit(10).forEach(System.out::println);

		//����
		Stream<Double> generate = Stream.generate(() -> Math.random());
		generate.forEach(System.out::println);
	}

	/**
	 * 4.Stream���м����
	 * ����м�������Ӷ���Ϊ��ˮ�ߣ���ˮ�߲�������ֹ�����ǲ������κδ���ģ���Ϊ�ֳ�Ϊ��������ֵ����
	 */
	public static void middle() {
		List<Integer> list = new ArrayList<>();
		list.stream()
			.map(s -> s + 1)  //ӳ��
			.flatMap(s -> Stream.of(s)) //��map��࣬����������ΪStream������list.add()��list.addAll()������
			.filter(s -> s < 1000)    //����
			.limit(5)   //����
			.skip(1)    //����
			.distinct() //ȥ��
			.sorted()   //��Ȼ����
			.sorted(Integer::compareTo); //�Զ�������
		/*
		 * ����map����������Ϊһ��Function�����ͽӿڵĶ���Ҳ���Ǵ���һ����������һ����������������Ǽ����е�ÿһ�����Iterator�����������ļ�������˼�붼��ࡣ
			ִ������ķ���ûʲô�ã���Ϊȱ����ֹ������
		 */
	}

	
	/**
	 * 5.Stream����ֹ����
	 */
	public static void end() {
		List<Integer> list = Arrays.asList(444, 555, 666, 777, 555);
		list.stream().allMatch((x) -> x == 555); // ����Ƿ�ƥ������Ԫ��
		list.stream().anyMatch(((x) -> x>600)); // ����Ƿ�����ƥ��һ��Ԫ��
		list.stream().noneMatch((x) -> x>500); //����Ƿ�û��ƥ������Ԫ��
		list.stream().findFirst(); // ���ص�һ��Ԫ��
		list.stream().findAny(); // ���ص�ǰ���е�����һ��Ԫ��
		list.stream().count(); // ��������Ԫ�ص��ܸ���
		list.stream().forEach(System.out::println); //�ڲ�����
		list.stream().max(Integer::compareTo); // �����������ֵ
		Optional<Integer> min = list.stream().min(Integer::compareTo);//����������Сֵ
		System.out.println("min "+min.get());
		
		
		/*reduce ����Լ����������Ԫ�ط�����������õ�һ��ֵ*/
		Integer reduce = list.stream()
		        .map(s -> (s + 1))
		        .reduce(0, (x, y) -> x + y);    //��Լ��0Ϊ��һ������x��Ĭ��ֵ��x�Ǽ����ķ���ֵ��yΪÿһ���ֵ��
		System.out.println(reduce);

		Optional<Integer> reduce1 = list.stream()
		        .map(s -> (s + 1))
		        .reduce((x, y) -> x + y);  // x�Ǽ����ķ���ֵ��Ĭ��Ϊ��һ���ֵ��yΪ���ÿһ���ֵ��
		System.out.println(reduce);
		
		
		/*collect���ռ���������ת��Ϊ������ʽ����ҪCollectors���һЩ������*/
		//ת����		
        Set<Integer> collect = list.stream()
                .collect(Collectors.toSet());

        List<Integer> collect2 = list.stream()
                .collect(Collectors.toList());

        HashSet<Integer> collect1 = list.stream()
                .collect(Collectors.toCollection(HashSet::new));

        //���� {group=[444, 555, 666, 777, 555]}
        Map<String, List<Integer>> collect3 = list.stream()
                .collect(Collectors.groupingBy((x) -> "group"));//������ֵ��ͬ�Ľ��з���
        System.out.println(collect3);

        //�༶���� {group={777=[777], 666=[666], 555=[555, 555], 444=[444]}}
        Map<String, Map<Integer, List<Integer>>> collect4 = list.stream()
                .collect(Collectors.groupingBy((x) -> "group", Collectors.groupingBy((x) -> x)));
        System.out.println(collect4);

        //���� {false=[444], true=[555, 666, 777, 555]}
        Map<Boolean, List<Integer>> collect5 = list.stream()
                .collect(Collectors.partitioningBy((x) -> x > 500));
        System.out.println(collect5);

        //����
        DoubleSummaryStatistics collect6 = list.stream()
                .collect(Collectors.summarizingDouble((x) -> x));
        System.out.println(collect6.getMax());
        System.out.println(collect6.getCount());

        //ƴ�� 444,555,666,777,555
        String collect7 = list.stream()
                .map(s -> s.toString())
                .collect(Collectors.joining(","));
        System.out.println(collect7);

        //���ֵ
        Optional<Integer> integer = list.stream()
                .collect(Collectors.maxBy(Integer::compare));
        System.out.println(integer.get());
	}

}
